package com.sz.biz.pay.account.service.impl;

import com.sz.biz.common.base.service.CurrencyService;
import com.sz.biz.common.constants.ErrorCodes;
import com.sz.biz.common.constants.MessagesCodes;
import com.sz.biz.common.constants.ModuleNames;
import com.sz.biz.common.constants.ShortName;
import com.sz.biz.pay.account.dto.BankCardShortDto;
import com.sz.biz.pay.account.dto.PayBankCardDto;
import com.sz.biz.pay.account.entity.Account;
import com.sz.biz.pay.account.entity.BankCard;
import com.sz.biz.pay.account.entity.ThirdPayAccount;
import com.sz.biz.pay.account.service.AccountService;
import com.sz.biz.pay.account.service.BankCardService;
import com.sz.biz.pay.account.service.ThirdPayAccountService;
import com.sz.biz.pay.constants.PayAction;
import com.sz.biz.pay.constants.PayConstant;
import com.sz.common.base.constants.UserActions;
import com.sz.common.base.dto.QResultDto;
import com.sz.common.base.dto.QueryParams;
import com.sz.common.base.dto.ResultDto;
import com.sz.common.base.exception.Exceptions;
import com.sz.common.base.i18n.I18nMessageHelper;
import com.sz.common.base.service.AbstractService;
import com.sz.common.base.utils.StringUtils;
import com.sz.common.base.utils.UUIDGenerator;
import com.sz.common.core.service.PrincipalLogUtils;
import com.sz.common.core.service.PrincipalUtils;
import com.sz.common.pay.common.SequenceGenerator;
import com.sz.common.pay.pingan.constant.CcyCode;
import com.sz.common.pay.pingan.constant.Constant;
import com.sz.common.pay.pingan.constant.SuperBankCodeData;
import com.sz.common.pay.pingan.constant.UnionPayBankData;
import com.sz.common.pay.pingan.core.client.PAPay;
import com.sz.common.pay.pingan.entity.account.*;
import com.sz.common.pay.pingan.entity.query.BindAccountsRequest;
import com.sz.common.pay.pingan.entity.query.BindAccountsResponse;
import com.sz.common.pay.pingan.entity.query.NumberAccountBalanceRequest;
import com.sz.common.pay.pingan.entity.query.NumberAccountBalanceResponse;
import com.sz.common.pay.pingan.exception.NoAvailableConnectException;
import com.sz.common.pay.pingan.exception.OperationFailedException;
import com.sz.common.pay.pingan.exception.PayCommonException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * Function: TODO: ADD FUNCTION <br>
 * Author: siqishangshu <br>
 * Date: 2017-11-02 18:06:00
 */
@Service
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class BankCardServiceImpl extends AbstractService implements BankCardService {

    private static final String BIND_CARD = "bindCard";
    @Autowired
    AccountService accountService;

    @Autowired
    ThirdPayAccountService thirdPayAccountService;

    @Autowired
    CurrencyService currencyService;

    @Override
    public int insert(BankCard entry) {
        return   dao.save(getMapperNamespace() + ShortName.INSERT, entry);
    }

    @Override
    public int delete(String id) {
        return  dao.delete(getMapperNamespace() + ShortName.DELETE_BY_ID, id);
    }

    @Override
    public int delete(List ids) {
        return dao.batchDelete(getMapperNamespace() + ShortName.DELETE_BY_IDS, ids);
    }

    @Override
    public int update(BankCard entry) {
        return dao.update(getSqlName("updateByPrimaryKeySelective"),entry);

    }

    @Override
    public BankCard select(String id) {
        return Optional.ofNullable((BankCard) dao.
                findForObject(getMapperNamespace() + ShortName.SELECT_BY_ID, id)).orElse(null);
    }

    @Override
    public List<BankCard> selectList(List ids) {
        return null;
    }

    @Override
    public List<BankCard> selectAll() {
        return null;
    }

    @Override
    public QResultDto selectList(QueryParams param) {
        return null;
    }

    @Override
    public int count(QueryParams param) {
        return 0;
    }

    @Override
    public int countAll() {
        return 0;
    }

    @Override
    public PayBankCardDto findNewestCard(String thirdPayAccountId) {
        BankCard bankCard = (BankCard) dao.findForObject(getSqlName("findNewestCard"), thirdPayAccountId);
        PayBankCardDto payBankCardDto = new PayBankCardDto();
        if (bankCard != null) {
            BeanUtils.copyProperties(bankCard, payBankCardDto);
        }
        return payBankCardDto;

    }

    @Override
    public int insertSelective(BankCard bankCard) {
        bankCard.setCreateTime(dao.getDbDate());
        return dao.save(getMapperNamespace() + ShortName.INSERT_SELECTIVE, bankCard);
    }

    @Override
    public void updateById(BankCard bankCard) {
        dao.update(getSqlName("updateById"), bankCard);
    }

    @Override
    public List<PayBankCardDto> findAllByThirdPayAccountId(String thirdPayAccountId) {
        List<BankCard> bankCards = dao.findForList(getSqlName("findAllByThirdPayAccountId"), thirdPayAccountId, BankCard.class);
        List<PayBankCardDto> payBankCardDtos = new ArrayList<>();
        for (BankCard bankCard : bankCards) {
            PayBankCardDto payBankCardDto = new PayBankCardDto();
            BeanUtils.copyProperties(bankCard, payBankCardDto);
            payBankCardDtos.add(payBankCardDto);
        }
        return payBankCardDtos;

    }

    @Override
    public void changeDeleteSign(BankCard bankCard) {
        dao.update(getSqlName("changeDeleteSign"), bankCard);
    }

    @Override
    public void changeStatusByCardNo(BankCard bankCard) {
        dao.update(getSqlName("changeStatusByCardNo"), bankCard);
    }

    /**
     * 会员绑定信息查询请求
     *
     * @param custAcctId
     * @return
     */
    @Override
    public ResultDto queryAccountCard(String custAcctId) {
        ResultDto resultDto = new ResultDto();
        String thirdLogNo = SequenceGenerator.getThirdLogNo();
        BindAccountsRequest bindAccountQueryRequest = new BindAccountsRequest();
        bindAccountQueryRequest.setSelectFlag(Constant.CardSelectFlag.ONE);
        bindAccountQueryRequest.setSupAcctId(Constant.SUP_ACCT_ID);
        bindAccountQueryRequest.setCustAcctId(custAcctId);
        bindAccountQueryRequest.setPageNum("1");
        BindAccountsResponse bindAccountQueryResponse = null;

        PrincipalLogUtils.addOperationLog(ModuleNames.BIZ, ModuleNames.BIZ_PAY, UserActions.REQUEST, PayAction.QUERY,
                makeBackData(thirdLogNo, bindAccountQueryRequest));
        Object object = null;
        try {
            bindAccountQueryResponse = (BindAccountsResponse) PAPay.sendMessage(thirdLogNo, bindAccountQueryRequest, BindAccountsResponse.class);
            resultDto.setData(bindAccountQueryResponse);

            object = bindAccountQueryResponse;
        } catch (NoAvailableConnectException e) {

            object = e.getMessage();
            throw Exceptions.bizException(ErrorCodes.ERROR_PAY_AVAILABLE_CONNECT);
        } catch (OperationFailedException e) {

            object = e.getErrorMessage();
            resultDto.setErrorCode(ErrorCodes.ERROR_PAY_OPERATION.getCode());
            resultDto.setMsg(e.getErrorMessage().getRspCode()+" "+ e.getErrorMessage().getRspMsg());
            resultDto.setData(e.getErrorMessage());
        } catch (PayCommonException e) {

            object = e.getMessage();
            throw Exceptions.bizException(ErrorCodes.ERROR_PAY_COMMON);
        } finally {
            PrincipalLogUtils.addOperationLog(ModuleNames.BIZ, ModuleNames.BIZ_PAY, UserActions.RESPONSE, PayAction.QUERY,
                    makeBackData(thirdLogNo, object));

        }
        return resultDto;
    }

    /**
     * 查询子账户余额请求
     *
     * @param custAcctId
     * @return
     */
    @Override
    public ResultDto queryAccountBalance(String custAcctId) {
        ResultDto resultDto = new ResultDto();
        String thirdLogNo = SequenceGenerator.getThirdLogNo();
        NumberAccountBalanceRequest numberAccountBalanceRequest = new NumberAccountBalanceRequest();
        numberAccountBalanceRequest.setSupAcctId(Constant.SUP_ACCT_ID); //资金汇总账号
        numberAccountBalanceRequest.setCustAcctId(custAcctId);
        numberAccountBalanceRequest.setReserve("");
        NumberAccountBalanceResponse numberAccountBalanceResponse = null;

        PrincipalLogUtils.addOperationLog(ModuleNames.BIZ, ModuleNames.BIZ_PAY, UserActions.REQUEST, PayAction.QUERYBALANCE,
                makeBackData(thirdLogNo, numberAccountBalanceRequest));
        Object object = null;
        try {
            numberAccountBalanceResponse = (NumberAccountBalanceResponse)
                    PAPay.sendMessage(thirdLogNo, numberAccountBalanceRequest, NumberAccountBalanceResponse.class);
            resultDto.setData(numberAccountBalanceResponse);

            object = numberAccountBalanceResponse;
        } catch (NoAvailableConnectException e) {

            object = e.getMessage();
            throw Exceptions.bizException(ErrorCodes.ERROR_PAY_AVAILABLE_CONNECT);
        } catch (OperationFailedException e) {

            object = e.getErrorMessage();
            resultDto.setErrorCode(ErrorCodes.ERROR_PAY_OPERATION.getCode());
            resultDto.setMsg(e.getErrorMessage().getRspCode()+" "+ e.getErrorMessage().getRspMsg());
            resultDto.setData(e.getErrorMessage());
        } catch (PayCommonException e) {

            object = e.getMessage();
            throw Exceptions.bizException(ErrorCodes.ERROR_PAY_COMMON);
        } finally {
            PrincipalLogUtils.addOperationLog(ModuleNames.BIZ, ModuleNames.BIZ_PAY, UserActions.RESPONSE, PayAction.QUERYBALANCE,
                    makeBackData(thirdLogNo, object));

        }
        return resultDto;
    }

    @Override
    public double getAccountBalance(String thirdPayId) {
        ResultDto resultDto = queryAccountBalance(thirdPayId);

        double totalBalance = 0;
        if (resultDto.getData() instanceof NumberAccountBalanceResponse) {
            NumberAccountBalanceResponse numberAccountBalanceResponse = (NumberAccountBalanceResponse) queryAccountBalance(thirdPayId).getData();
            String balance = numberAccountBalanceResponse.getTotalBalance();
            totalBalance = Double.parseDouble(balance);
        }


        return totalBalance;

    }

    /**
     * 会员绑定提现账户请求
     *
     * @param account         账户
     * @param thirdPayAccount 第三方账户
     * @param payBankCardDto  银行卡
     * @return
     */
    @Override
    public ResultDto bindAccountAuth(Account account, ThirdPayAccount thirdPayAccount, PayBankCardDto payBankCardDto) {
        ResultDto resultDto = new ResultDto();
        String thirdLogNo = SequenceGenerator.getThirdLogNo();
        BindAccountAuthRequest bindAccountAuthRequest = new BindAccountAuthRequest();
        bindAccountAuthRequest.setCustAcctId(thirdPayAccount.getThirdPayId());
        bindAccountAuthRequest.setThirdCustId(thirdPayAccount.getAccountId());
        bindAccountAuthRequest.setSupAcctId(Constant.SUP_ACCT_ID);
        bindAccountAuthRequest.setCustName(account.getCustName());
        bindAccountAuthRequest.setIdType(account.getIdType());
        bindAccountAuthRequest.setIdCode(account.getIdCode());
        bindAccountAuthRequest.setAcctId(payBankCardDto.getCardNo());
        bindAccountAuthRequest.setBankType(Constant.BankType.OTHER);
        bindAccountAuthRequest.setBankName(payBankCardDto.getBank());
        bindAccountAuthRequest.setBankCode(UnionPayBankData.getBankByName(payBankCardDto.getBank()).getCode());
        bindAccountAuthRequest.setSBankCode(SuperBankCodeData.getNetBankCodeByShortName(payBankCardDto.getBank()).getNetCode());
        bindAccountAuthRequest.setMobilePhone(account.getMobilePhone());
        bindAccountAuthRequest.setReserve("");
        BindAccountAuthResponse bindAccountAuthResponse = null;
        PrincipalLogUtils.addOperationLog(ModuleNames.BIZ, ModuleNames.BIZ_PAY, UserActions.REQUEST, PayAction.BINDCARD,
                makeBackData(thirdLogNo, bindAccountAuthRequest));
        Object object = null;
        try {
            bindAccountAuthResponse = (BindAccountAuthResponse) PAPay.sendMessage(thirdLogNo, bindAccountAuthRequest, BindAccountAuthResponse.class);
            resultDto.setData(true);
            resultDto.setMsg(I18nMessageHelper.getI18nMessage(MessagesCodes.MODULE_PAY_ADD_ACCOUNT_SUCCESS, null));
            object = bindAccountAuthResponse;
        } catch (NoAvailableConnectException e) {
            object = e.getMessage();
            throw Exceptions.bizException(ErrorCodes.ERROR_PAY_AVAILABLE_CONNECT);
        } catch (OperationFailedException e) {
            object = e.getErrorMessage();
            resultDto.setErrorCode(ErrorCodes.ERROR_PAY_OPERATION.getCode());
            resultDto.setMsg(e.getErrorMessage().getRspCode()+" "+ e.getErrorMessage().getRspMsg());
            resultDto.setData(e.getErrorMessage());
        } catch (PayCommonException e) {
            object = e.getMessage();
            throw Exceptions.bizException(ErrorCodes.ERROR_PAY_COMMON);
        } finally {
            PrincipalLogUtils.addOperationLog(ModuleNames.BIZ, ModuleNames.BIZ_PAY, UserActions.RESPONSE, PayAction.OPENACCOUNT,
                    makeBackData(thirdLogNo, object));
        }
        return resultDto;
    }


    /**
     * 验证鉴权金额请求
     *
     * @param custAcctId
     * @param thirdCustId
     * @param acctId
     * @param tranAmount
     * @return
     */
    @Override
    public ResultDto bindAccountAuthQuota(String custAcctId, String thirdCustId, String acctId, String tranAmount) {
        ResultDto resultDto = new ResultDto();
        String thirdLogNo = SequenceGenerator.getThirdLogNo();
        BindAccountAuthQuotaRequest bindAccountAuthQuotaRequest = new BindAccountAuthQuotaRequest();
        bindAccountAuthQuotaRequest.setSupAcctId(Constant.SUP_ACCT_ID);
        bindAccountAuthQuotaRequest.setCustAcctId(custAcctId);
        bindAccountAuthQuotaRequest.setThirdCustId(thirdCustId);
        bindAccountAuthQuotaRequest.setAcctId(acctId);
        bindAccountAuthQuotaRequest.setCcyCode(CcyCode.RMB);
        bindAccountAuthQuotaRequest.setTranAmount(tranAmount);
        bindAccountAuthQuotaRequest.setReserve("");
        BindAccountAuthQuotaResponse bindAccountAuthQuotaResponse = null;
        PrincipalLogUtils.addOperationLog(ModuleNames.BIZ, ModuleNames.BIZ_PAY, UserActions.REQUEST, PayAction.VERIFYBIND,
                makeBackData(thirdLogNo, bindAccountAuthQuotaRequest));
        Object object = null;

        try {
            bindAccountAuthQuotaResponse = (BindAccountAuthQuotaResponse) PAPay.sendMessage(thirdLogNo, bindAccountAuthQuotaRequest, BindAccountAuthQuotaResponse.class);
            resultDto.setData(true);
            resultDto.setMsg(I18nMessageHelper.getI18nMessage(MessagesCodes.MODULE_PAY_BANKCARD_ACCOUNT_VERIFICATION_PASS, null));
            object = bindAccountAuthQuotaResponse;
        } catch (NoAvailableConnectException e) {

            object = e.getMessage();
            throw Exceptions.bizException(ErrorCodes.ERROR_PAY_AVAILABLE_CONNECT);
        } catch (OperationFailedException e) {

            object = e.getErrorMessage();
            resultDto.setErrorCode(ErrorCodes.ERROR_PAY_OPERATION.getCode());
            resultDto.setMsg(e.getErrorMessage().getRspCode()+" "+ e.getErrorMessage().getRspMsg());
            resultDto.setData(e.getErrorMessage());
        } catch (PayCommonException e) {

            object = e.getMessage();
            throw Exceptions.bizException(ErrorCodes.ERROR_PAY_COMMON);
        } finally {
            PrincipalLogUtils.addOperationLog(ModuleNames.BIZ, ModuleNames.BIZ_PAY, UserActions.RESPONSE, PayAction.VERIFYBIND,
                    makeBackData(thirdLogNo, object));

        }
        return resultDto;
    }

    /**
     * 会员解绑提现账户请求
     *
     * @param acctId
     * @param custAcctId
     * @param thirdCustId
     * @return
     */
    @Override
    public ResultDto unbindCard(String acctId, String custAcctId, String thirdCustId) {
        ResultDto resultDto = new ResultDto();
        String thirdLogNo = SequenceGenerator.getThirdLogNo();
        UnBindAccountRequest unBindAccountRequest = new UnBindAccountRequest();
        unBindAccountRequest.setAcctId(acctId);
        unBindAccountRequest.setCustAcctId(custAcctId);
        unBindAccountRequest.setSupAcctId(Constant.SUP_ACCT_ID);
        unBindAccountRequest.setThirdCustId(thirdCustId);
        UnBindAccountResponse unBindAccountResponse = null;

        PrincipalLogUtils.addOperationLog(ModuleNames.BIZ, ModuleNames.BIZ_PAY, UserActions.REQUEST, PayAction.UNBINGCARD,
                makeBackData(thirdLogNo, unBindAccountRequest));
        Object object = null;
        try {
            unBindAccountResponse = (UnBindAccountResponse) PAPay.sendMessage(thirdLogNo, unBindAccountRequest, UnBindAccountResponse.class);
            resultDto.setData(true);
            resultDto.setMsg(I18nMessageHelper.getI18nMessage(MessagesCodes.MODULE_PAY_BANKCARD_UNBIND_SUCCESS, null));
            object = unBindAccountResponse;
        } catch (NoAvailableConnectException e) {

            object = e.getMessage();
            throw Exceptions.bizException(ErrorCodes.ERROR_PAY_AVAILABLE_CONNECT);
        } catch (OperationFailedException e) {

            object = e.getErrorMessage();
            resultDto.setErrorCode(ErrorCodes.ERROR_PAY_OPERATION.getCode());
            resultDto.setMsg(e.getErrorMessage().getRspCode()+" "+ e.getErrorMessage().getRspMsg());
            resultDto.setData(e.getErrorMessage());
        } catch (PayCommonException e) {

            object = e.getMessage();
            throw Exceptions.bizException(ErrorCodes.ERROR_PAY_COMMON);

        } finally {
            PrincipalLogUtils.addOperationLog(ModuleNames.BIZ, ModuleNames.BIZ_PAY, UserActions.RESPONSE, PayAction.UNBINGCARD,
                    makeBackData(thirdLogNo, object));

        }
        return resultDto;
    }

    /**
     * 绑定银行卡
     *
     * @param payBankCardDto 银行卡信息
     */
    @Override
    public ResultDto bindAccountCard(PayBankCardDto payBankCardDto) {
        //根据第三方账户ID查询第三方账户
        ThirdPayAccount thirdPayAccount = thirdPayAccountService.findById(payBankCardDto.getThirdPayAccountId());
        if (null == thirdPayAccount) {
            throw Exceptions.bizException(ErrorCodes.ERROR_PAY_THIRDACCOUNT_NOT_EXISTS);
        }
        //根据账户ID查询账户
        Account account = accountService.findAccountById(thirdPayAccount.getAccountId());
        if (null == account) {
            throw Exceptions.bizException(ErrorCodes.ERROR_PAY_ACCOUNT_NOT_EXISTS);
        }
        ResultDto resultDto = this.bindAccountAuth(account, thirdPayAccount, payBankCardDto);
        if (resultDto.getData().equals(true)) {
            BankCard bankCard = new BankCard();
            BeanUtils.copyProperties(payBankCardDto, bankCard);
            setDefaultData(bankCard);
            this.insertSelective(bankCard);
        }

        return resultDto;
    }

    /**
     * 设置初始数据
     *
     * @param bankCard
     */
    private void setDefaultData(BankCard bankCard) {
        ThirdPayAccount thirdPayAccount = thirdPayAccountService.findById(bankCard.getThirdPayAccountId());
        if (null == thirdPayAccount) {
            throw Exceptions.bizException(ErrorCodes.ERROR_PAY_THIRDACCOUNT_NOT_EXISTS);
        }
        Account account = accountService.findAccountById(thirdPayAccount.getAccountId());
        if (null == account) {
            throw Exceptions.bizException(ErrorCodes.ERROR_PAY_ACCOUNT_NOT_EXISTS);
        }
        int userId = PrincipalUtils.getAccountId();
        bankCard.setId(UUIDGenerator.generateRandomUUID());
        bankCard.setIdType(account.getIdType());
        bankCard.setIdCode(account.getIdCode());
        bankCard.setStatus(PayConstant.BindCardStatus.VERIFIED);
        bankCard.setIsDefault(false);
        bankCard.setIsDeleted(false);
        bankCard.setCreateUserId(userId);
        bankCard.setLastUpdateUserId(userId);
        String sBankCode = SuperBankCodeData.getNetBankCodeByShortName(bankCard.getBank()).getNetCode();
        bankCard.setsBankCode(sBankCode);
        if (bankCard.getBank() == PayConstant.BankName.PINGAN) {
            bankCard.setBankType(1);
        } else {
            bankCard.setBankType(2);
        }

    }

    /**
     * 验证银行卡绑定
     *
     * @param payBankCardDto
     */
    @Override

    public ResultDto verifyBindCard(PayBankCardDto payBankCardDto) {
        ThirdPayAccount thirdPayAccount = thirdPayAccountService.findById(payBankCardDto.getThirdPayAccountId());
        if (null == thirdPayAccount) {
            throw Exceptions.bizException(ErrorCodes.ERROR_PAY_THIRDACCOUNT_NOT_EXISTS);
        }
        //根据账户ID查询账户
        Account account = accountService.findAccountById(thirdPayAccount.getAccountId());
        if (null == account) {
            throw Exceptions.bizException(ErrorCodes.ERROR_PAY_ACCOUNT_NOT_EXISTS);
        }


        ResultDto resultDto = this.bindAccountAuthQuota(thirdPayAccount.getThirdPayId(), account.getId(), payBankCardDto.getCardNo(), payBankCardDto.getAmount());
        if (resultDto.getData().equals(true)) {
            //修改银行账户状态
            BankCard bankCard = new BankCard();
            bankCard.setCardNo(payBankCardDto.getCardNo());
            bankCard.setStatus(PayConstant.BindCardStatus.BOUND);
            this.changeStatusByCardNo(bankCard);
        }

        return resultDto;
    }

    /**
     * 解绑银行卡
     */
    @Override
    public ResultDto unbindAccountCard(String bankCardId) {
        //根据账户id查询账户
        BankCard bankCard = this.select(bankCardId);
        if (null == bankCard) {
            throw Exceptions.bizException(ErrorCodes.ERROR_PAY_ACCOUNT_NOT_EXISTS);
        }
        //根据第三方账户ID查询第三方账户
        ThirdPayAccount thirdPayAccount = thirdPayAccountService.findById(bankCard.getThirdPayAccountId());
        if (null == thirdPayAccount) {
            throw Exceptions.bizException(ErrorCodes.ERROR_PAY_THIRDACCOUNT_NOT_EXISTS);
        }
        //根据账户ID查询账户
        Account account = accountService.findAccountById(thirdPayAccount.getAccountId());
        if (null == account) {
            throw Exceptions.bizException(ErrorCodes.ERROR_PAY_ACCOUNT_NOT_EXISTS);
        }
        ResultDto resultDto = this.unbindCard(bankCard.getCardNo(), thirdPayAccount.getThirdPayId(), account.getId());
        if (resultDto.getData().equals(true)) {
            bankCard.setStatus(PayConstant.BindCardStatus.UNBIND);
            bankCard.setIsDeleted(true);
            this.changeDeleteSign(bankCard);
        }

        return resultDto;
    }

    @Override
    public boolean sendSms(String mobilePhone) {

//        //生成手机验证码
//        PassWordCreate pwc = new PassWordCreate();
//        String validateCode = pwc.createValidateCode(6);
//
//        //将验证码插入redis
//        Jedis jedis = RedisPoolManager.getJedis();
//        jedis.set(mobilePhone + BIND_CARD, validateCode);
//        jedis.expire(mobilePhone + BIND_CARD, validateCodeTimeOut);
//
//        //组装短信内容进行发送
//        SmsBodyDto smsBodyDto = new SmsBodyDto();
//
//        String[] templateKeyArray = templateKey.split(",");
//
//        for (int i = 0; i < templateKeyArray.length; i++) {
//
//            smsBodyDto.getSmsTemplateKey().add(templateKeyArray[i]);
//        }
//
//        smsBodyDto.getSmsTemplateValue().add(validateCode);
//
//        smsService.sendSms(mobilePhone, smsTemplateCode, smsBodyDto);
//
//        jedis.close();
        return true;
    }

    @Override
    public BankCard getByCardNo(String cardNo) {
        return (BankCard) dao.findForObject(getSqlName("getByCardNo"), cardNo);
    }

    @Override
    public BankCard getByThirdPayAccountId(String thirdPayAccountId) {
        return (BankCard) dao.findForObject(getSqlName("getByThirdPayAccountId"),thirdPayAccountId);
    }

    @Override
    public List<BankCard> getVerifiedCard(String thirdPayAccountId) {
        return dao.findForList(getSqlName("getVerifiedCard"), thirdPayAccountId, BankCard.class);
    }

    /**
     * 根据第三方账户id查询银行卡数量
     *
     * @param thirdPayAccountId
     * @return
     */
    @Override
    public int getCardNum(String thirdPayAccountId) {
        return (Integer) dao.findForObject(getSqlName("getCardNum"), thirdPayAccountId);
    }

    @Override
    public ResultDto checkCardExist(String cardNo) {
        ResultDto resultDto = new ResultDto();
        //校验银行卡号
        boolean isRight = checkBankCard(cardNo);
        //判断银行卡号是否存在
        int cardNum = (Integer) dao.findForObject(getSqlName("checkCardExist"), cardNo);
        if (!isRight) {
            resultDto.setData(false);
            resultDto.setErrorCode(ErrorCodes.ERROR_PAY_BANKCARD_FORM_ERROR.getCode());
            resultDto.setMsg(I18nMessageHelper.getI18nMessage(ErrorCodes.ERROR_PAY_BANKCARD_FORM_ERROR.getMessageKey(), null));
        }
        if (cardNum != 0) {
            resultDto.setData(false);
            resultDto.setErrorCode(ErrorCodes.ERROR_PAY_BANKCARD_EXISTS.getCode());
            resultDto.setMsg(I18nMessageHelper.getI18nMessage(ErrorCodes.ERROR_PAY_BANKCARD_EXISTS.getMessageKey(), null));
        }
        resultDto.setData(true);
        return resultDto;
    }


    //TODO
    @Override
    public ResultDto getBankInfo(String thirdPayAccountId) {

        ResultDto resultDto = new ResultDto();
        BankCard bankCard = this.getByThirdPayAccountId(thirdPayAccountId);
        if(null == bankCard){
            throw Exceptions.bizException(ErrorCodes.ERROR_PAY_BANKCARD_NOT_EXISTS);
        }
        BankCardShortDto bankCardShortDto = new BankCardShortDto();
        BeanUtils.copyProperties(bankCard, bankCardShortDto);
        resultDto.setData(bankCardShortDto);
        return resultDto;

    }

    @Override
    protected String getMapperNamespace() {
        return "com.sz.biz.pay.account.BankCardMapper";
    }

    private Map makeBackData(String thirdLogNo, Object obj) {
        Map map = new HashMap<>(16);
        map.put("thirdLogNo", thirdLogNo);
        map.put(obj.getClass().getSimpleName(), obj);

        return map;
    }


    private void checkMainDataValid(BankCard bankCard) {
        if (null != bankCard) {
            if (StringUtils.isEmpty(bankCard.getThirdPayAccountId())) {
                throw Exceptions.bizException(ErrorCodes.ERROR_ARGUMENT_EMPTY, "thirdPayAccountId");
            }
            if (StringUtils.isEmpty(bankCard.getSubbranch())) {
                throw Exceptions.bizException(ErrorCodes.ERROR_ARGUMENT_EMPTY, "subbranch");
            }
            if (StringUtils.isEmpty(bankCard.getCardNo())) {
                throw Exceptions.bizException(ErrorCodes.ERROR_ARGUMENT_EMPTY, "cardNo");
            }


        }
    }

    /**
     * 校验银行卡卡号
     *
     * @param bankCard
     * @return
     */
    public static boolean checkBankCard(String bankCard) {
        if (bankCard.length() < 15 || bankCard.length() > 19) {
            return false;
        }
        char bit = getBankCardCheckCode(bankCard.substring(0, bankCard.length() - 1));
        if (bit == 'N') {
            return false;
        }
        return bankCard.charAt(bankCard.length() - 1) == bit;
    }

    /**
     * 从不含校验位的银行卡卡号采用 Luhm 校验算法获得校验位
     *
     * @param nonCheckCodeBankCard
     * @return
     */
    public static char getBankCardCheckCode(String nonCheckCodeBankCard) {
        if (nonCheckCodeBankCard == null || nonCheckCodeBankCard.trim().length() == 0
                || !nonCheckCodeBankCard.matches("\\d+")) {
            //如果传的不是数据返回N
            return 'N';
        }
        char[] chs = nonCheckCodeBankCard.trim().toCharArray();
        int luhmSum = 0;
        for (int i = chs.length - 1, j = 0; i >= 0; i--, j++) {
            int k = chs[i] - '0';
            if (j % 2 == 0) {
                k *= 2;
                k = k / 10 + k % 10;
            }
            luhmSum += k;
        }
        return (luhmSum % 10 == 0) ? '0' : (char) ((10 - luhmSum % 10) + '0');
    }


}
